home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1999 Spring / macformat-077.iso / Shareware Plus / Development / SpriteWorld 2.2 / SpriteWorld Examples / Shark Attack / Sources & Headers / SpriteMoveProcs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-22  |  13.7 KB  |  498 lines  |  [TEXT/CWIE]

  1. #include <SWIncludes.h>
  2. #include "Shark Attack.h"
  3. #include "NewSprite.h"
  4. #include "SpriteMoveProcs.h"
  5. #include "GlobalVariables.h"
  6. #include "SWSounds.h"
  7.  
  8.  
  9. //--------------------------------------------------------------------------------
  10. //   SubSpriteMoveProc
  11. //--------------------------------------------------------------------------------
  12.  
  13. SW_FUNC void SubSpriteMoveProc(SpritePtr subSpriteP)
  14. {
  15.     double            horizDelta, vertDelta;
  16.     short            bulletSpeed;
  17.     SpritePtr        newBulletSpriteP;
  18.     SubStructPtr    subStructP = (SubStructPtr)subSpriteP;
  19.     
  20.     horizDelta = subStructP->horizDelta;
  21.     vertDelta = subStructP->vertDelta;
  22.     
  23.     if (gKeys.left)                        // Increase speed if keys are down
  24.     {
  25.         if (subStructP->curDirection != kLeftDirection)
  26.         {
  27.             subStructP->curDirection = kLeftDirection;
  28.             SWSetCurrentFrameIndex(subSpriteP, kSubLeftFrameIndex);
  29.         }
  30.         
  31.         horizDelta -= kSubAcceleration;
  32.         if (horizDelta < -kSubMaxSpeed)
  33.             horizDelta = -kSubMaxSpeed;
  34.     }
  35.     else if (gKeys.right)
  36.     {
  37.         if (subStructP->curDirection != kRightDirection)
  38.         {
  39.             subStructP->curDirection = kRightDirection;
  40.             SWSetCurrentFrameIndex(subSpriteP, kSubRightFrameIndex);
  41.         }
  42.         
  43.         horizDelta += kSubAcceleration;
  44.         if (horizDelta > kSubMaxSpeed)
  45.             horizDelta = kSubMaxSpeed;
  46.     }
  47.     else                                // Decrease speed if no key is held
  48.     {
  49.         if (horizDelta > 0)
  50.         {
  51.             horizDelta -= kSubDeacceleration;
  52.             if (horizDelta < 0)
  53.                 horizDelta = 0;
  54.         }
  55.         else if (horizDelta < 0)
  56.         {
  57.             horizDelta += kSubDeacceleration;
  58.             if (horizDelta > 0)
  59.                 horizDelta = 0;
  60.         }
  61.     }
  62.     
  63.     
  64.     if (gKeys.up)                            // Increase speed if keys are down
  65.     {
  66.         vertDelta -= kSubAcceleration;
  67.         if (vertDelta < -kSubMaxSpeed)
  68.             vertDelta = -kSubMaxSpeed;
  69.     }
  70.     else if (gKeys.down)
  71.     {
  72.         vertDelta += kSubAcceleration;
  73.         if (vertDelta > kSubMaxSpeed)
  74.             vertDelta = kSubMaxSpeed;
  75.     }
  76.     else                                        // Decrease speed if no key is held
  77.     {
  78.         if (vertDelta > 0)
  79.         {
  80.             vertDelta -= kSubDeacceleration;
  81.             if (vertDelta < 0)
  82.                 vertDelta = 0;
  83.         }
  84.         else if (vertDelta < 0)
  85.         {
  86.             vertDelta += kSubDeacceleration;
  87.             if (vertDelta > 0)
  88.                 vertDelta = 0;
  89.         }
  90.     }
  91.  
  92.  
  93.     subStructP->horizDelta = horizDelta;
  94.     subStructP->vertDelta = vertDelta;
  95.  
  96.     subStructP->horizPos += subStructP->horizDelta;
  97.     subStructP->vertPos += subStructP->vertDelta;
  98.     
  99.     
  100.         // Keep within moveBounds
  101.     if (subStructP->vertPos < subSpriteP->moveBoundsRect.top)
  102.     {
  103.         subStructP->vertDelta = 0;
  104.         subStructP->vertPos = subSpriteP->moveBoundsRect.top;
  105.     }
  106.     else if (subStructP->vertPos + kSubHeight > subSpriteP->moveBoundsRect.bottom)
  107.     {
  108.         subStructP->vertDelta = 0;
  109.         subStructP->vertPos = subSpriteP->moveBoundsRect.bottom - kSubHeight;
  110.     }
  111.     
  112.     if (subStructP->horizPos < subSpriteP->moveBoundsRect.left)
  113.     {
  114.         subStructP->horizDelta = 0;
  115.         subStructP->horizPos = subSpriteP->moveBoundsRect.left;
  116.     }
  117.     else if (subStructP->horizPos + kSubWidth > subSpriteP->moveBoundsRect.right)
  118.     {
  119.         subStructP->horizDelta = 0;
  120.         subStructP->horizPos = subSpriteP->moveBoundsRect.right - kSubWidth;
  121.     }
  122.     
  123.     SWMoveSprite(subSpriteP, subStructP->horizPos, subStructP->vertPos);
  124.     
  125.     
  126.     if (gKeys.shoot || gKeys.shift)
  127.     {
  128.         if (subStructP->canShoot)
  129.         {
  130.             subStructP->canShoot = false;
  131.         
  132.             if ( (subStructP->numBulletsOnScreen < kMaxNumBullets) || kMachineGun)
  133.             {
  134.                 short    stereoPos;
  135.                 
  136.                 stereoPos = GetStereoPositionOfSprite(subSpriteP, &gSpriteWorldP->backRect);
  137.                 PlaySound2(kShootBulletSnd, 3, kReplaceSameSound, 256, stereoPos, k22khz, false);
  138.                 
  139.                 newBulletSpriteP = NewBulletSprite();
  140.                 ((BulletStructPtr)newBulletSpriteP)->parentStructP = subStructP;
  141.                 subStructP->numBulletsOnScreen++;
  142.                 gLastBulletP = newBulletSpriteP;
  143.                 
  144.                 if (kMachineGun)
  145.                     bulletSpeed = kMachineGunSpeed;
  146.                 else
  147.                     bulletSpeed = kNormalBulletSpeed;
  148.                 
  149.                 if (subStructP->curDirection == kLeftDirection)
  150.                 {
  151.                     newBulletSpriteP->horizMoveDelta = -bulletSpeed;
  152.                     newBulletSpriteP->horizMoveDelta += subStructP->horizDelta;
  153.                     SWSetSpriteLocation(newBulletSpriteP, 
  154.                         subSpriteP->destFrameRect.left - kBulletWidth, 
  155.                         subSpriteP->destFrameRect.top + 8);
  156.                 }
  157.                 else
  158.                 {
  159.                     newBulletSpriteP->horizMoveDelta = bulletSpeed;
  160.                     newBulletSpriteP->horizMoveDelta += subStructP->horizDelta;
  161.                     SWSetSpriteLocation(newBulletSpriteP, 
  162.                         subSpriteP->destFrameRect.right, 
  163.                         subSpriteP->destFrameRect.top + 8);
  164.                 }
  165.             }
  166.         }
  167.         else if (kMachineGun)
  168.         {
  169.             subStructP->nextShotDelay++;
  170.             if (subStructP->nextShotDelay >= kNextShotDelay)
  171.             {
  172.                 subStructP->nextShotDelay = 0;
  173.                 subStructP->canShoot = true;
  174.             }
  175.         }
  176.     }
  177.     else if (kMachineGun && subStructP->canShoot == false)
  178.     {
  179.         subStructP->nextShotDelay++;
  180.         if (subStructP->nextShotDelay >= kNextShotDelay)
  181.         {
  182.             subStructP->nextShotDelay = 0;
  183.             subStructP->canShoot = true;
  184.         }
  185.     }
  186.     else
  187.     {
  188.         subStructP->canShoot = true;
  189.     }
  190. }
  191.  
  192.  
  193. //--------------------------------------------------------------------------------
  194. //   LevelDoneSubMoveProc - installed when the level is done - slows sub to a stop
  195. //--------------------------------------------------------------------------------
  196.  
  197. SW_FUNC void LevelDoneSubMoveProc(SpritePtr subSpriteP)
  198. {
  199.     double            horizDelta, vertDelta;
  200.     SubStructPtr    subStructP = (SubStructPtr)subSpriteP;
  201.     
  202.     horizDelta = subStructP->horizDelta;
  203.     vertDelta = subStructP->vertDelta;
  204.     
  205.         // Slow the sub down if it's moving
  206.     if (horizDelta > 0)
  207.     {
  208.         horizDelta -= kSubDeacceleration;
  209.         if (horizDelta < 0)
  210.             horizDelta = 0;
  211.     }
  212.     else if (horizDelta < 0)
  213.     {
  214.         horizDelta += kSubDeacceleration;
  215.         if (horizDelta > 0)
  216.             horizDelta = 0;
  217.     }
  218.     
  219.     if (vertDelta > 0)
  220.     {
  221.         vertDelta -= kSubDeacceleration;
  222.         if (vertDelta < 0)
  223.             vertDelta = 0;
  224.     }
  225.     else if (vertDelta < 0)
  226.     {
  227.         vertDelta += kSubDeacceleration;
  228.         if (vertDelta > 0)
  229.             vertDelta = 0;
  230.     }
  231.  
  232.  
  233.     subStructP->horizDelta = horizDelta;
  234.     subStructP->vertDelta = vertDelta;
  235.  
  236.     subStructP->horizPos += subStructP->horizDelta;
  237.     subStructP->vertPos += subStructP->vertDelta;
  238.     
  239.     
  240.         // Keep within moveBounds
  241.     if (subStructP->vertPos < subSpriteP->moveBoundsRect.top)
  242.     {
  243.         subStructP->vertDelta = 0;
  244.         subStructP->vertPos = subSpriteP->moveBoundsRect.top;
  245.     }
  246.     else if (subStructP->vertPos + kSubHeight > subSpriteP->moveBoundsRect.bottom)
  247.     {
  248.         subStructP->vertDelta = 0;
  249.         subStructP->vertPos = subSpriteP->moveBoundsRect.bottom - kSubHeight;
  250.     }
  251.     
  252.     if (subStructP->horizPos < subSpriteP->moveBoundsRect.left)
  253.     {
  254.         subStructP->horizDelta = 0;
  255.         subStructP->horizPos = subSpriteP->moveBoundsRect.left;
  256.     }
  257.     else if (subStructP->horizPos + kSubWidth > subSpriteP->moveBoundsRect.right)
  258.     {
  259.         subStructP->horizDelta = 0;
  260.         subStructP->horizPos = subSpriteP->moveBoundsRect.right - kSubWidth;
  261.     }
  262.     
  263.     SWMoveSprite(subSpriteP, subStructP->horizPos, subStructP->vertPos);
  264. }
  265.  
  266.  
  267. //--------------------------------------------------------------------------------
  268. //   DeadSubSpriteMoveProc - installed as the sub's moveProc when the sub gets hit
  269. //--------------------------------------------------------------------------------
  270.  
  271. SW_FUNC void DeadSubSpriteMoveProc(SpritePtr subSpriteP)
  272. {
  273.     SubStructPtr subStructP = (SubStructPtr)subSpriteP;
  274.     
  275.     if (subSpriteP->oldFrameRect.top >= subSpriteP->moveBoundsRect.bottom)
  276.     {
  277.         gSubIsStillOnScreen = false;
  278.     }
  279.     else
  280.     {
  281.         subStructP->vertDelta += .05;
  282.         if (subStructP->vertDelta > 5)
  283.             subStructP->vertDelta = 5;
  284.         
  285.         subStructP->vertPos += subStructP->vertDelta;
  286.         
  287.         SWMoveSprite(subSpriteP, subStructP->horizPos, subStructP->vertPos);
  288.     }
  289. }
  290.  
  291.  
  292. ///--------------------------------------------------------------------------------------
  293. //  BulletSpriteMoveProc
  294. ///--------------------------------------------------------------------------------------
  295.  
  296. SW_FUNC void BulletSpriteMoveProc(SpritePtr srcSpriteP)
  297. {
  298.         // Don't move the sprite if it was just now created
  299.         // and hasn't even been drawn yet.
  300.     if (srcSpriteP->needsToBeDrawn)
  301.         return;
  302.     
  303.     SWOffsetSprite(srcSpriteP, srcSpriteP->horizMoveDelta, 0);
  304.     
  305.     if (srcSpriteP->oldFrameRect.right < srcSpriteP->moveBoundsRect.left ||
  306.         srcSpriteP->oldFrameRect.left > srcSpriteP->moveBoundsRect.right)
  307.     {
  308.         ((BulletStructPtr)srcSpriteP)->parentStructP->numBulletsOnScreen--;
  309.         SWRemoveSpriteFromAnimation(gSpriteWorldP, srcSpriteP, true);
  310.         if (srcSpriteP == gLastBulletP)
  311.             gLastBulletP = NULL;
  312.     }
  313.     
  314.         // Update the stereo position of the bullet sound based on the position
  315.         // of the bullet that was shot most recently.
  316.     if (srcSpriteP == gLastBulletP)
  317.     {
  318.         short    stereoPos, channelNum;
  319.         
  320.         channelNum = FindSound(kShootBulletSnd);
  321.         stereoPos = GetStereoPositionOfSprite(srcSpriteP, &gSpriteWorldP->backRect);
  322.         SetStereoPosition(channelNum, stereoPos);
  323.     }
  324. }
  325.  
  326.  
  327. ///--------------------------------------------------------------------------------------
  328. //  FishSpriteMoveProc
  329. ///--------------------------------------------------------------------------------------
  330.  
  331. SW_FUNC void FishSpriteMoveProc(SpritePtr fishSpriteP)
  332. {
  333.     FishStructPtr    fishStructP = (FishStructPtr)fishSpriteP;
  334.     
  335.         // If the fish was just hit and flashed white, change back to normal drawProc
  336.     if (fishStructP->hitCounter > 0)
  337.     {
  338.         if (--fishStructP->hitCounter == 0)
  339.         {
  340.             fishSpriteP->needsToBeDrawn = true;
  341.             SWSetSpriteDrawProc(fishSpriteP, gSpriteMaskDrawProc);
  342.         }
  343.     }
  344.     
  345.         // Don't move the fish if it was hit recently
  346.     if (fishStructP->moveDelay > 0)
  347.     {
  348.         fishStructP->moveDelay--;
  349.         return;
  350.     }
  351.     
  352.     SWOffsetSprite(fishSpriteP, fishSpriteP->horizMoveDelta, 0);
  353.     
  354.     if ( (fishSpriteP->oldFrameRect.right < fishSpriteP->moveBoundsRect.left &&
  355.          fishSpriteP->horizMoveDelta < 0) ||
  356.          (fishSpriteP->oldFrameRect.left > fishSpriteP->moveBoundsRect.right &&
  357.          fishSpriteP->horizMoveDelta > 0) )
  358.     {
  359.         gNumFishOnScreen--;
  360.         SWRemoveSpriteFromAnimation(gSpriteWorldP, fishSpriteP, true);
  361.     }
  362. }
  363.  
  364.  
  365. ///--------------------------------------------------------------------------------------
  366. //  SharkSpriteMoveProc
  367. ///--------------------------------------------------------------------------------------
  368.  
  369. SW_FUNC void SharkSpriteMoveProc(SpritePtr sharkSpriteP)
  370. {
  371.     SharkStructPtr    sharkStructP = (SharkStructPtr)sharkSpriteP;
  372.     SubStructPtr    subStructP = (SubStructPtr)gSubCloneP;
  373.     short            sharkMid = sharkSpriteP->oldFrameRect.top + kSharkHeight/2;
  374.     short            subMid = gSubCloneP->oldFrameRect.top + kSubHeight/2;
  375.     
  376.     
  377.         // If the fish was just hit and flashed white, change back to normal drawProc
  378.     if (sharkStructP->hitCounter > 0)
  379.     {
  380.         if (--sharkStructP->hitCounter == 0)
  381.         {
  382.             sharkSpriteP->needsToBeDrawn = true;
  383.             SWSetSpriteDrawProc(sharkSpriteP, gSpriteMaskDrawProc);
  384.         }
  385.     }
  386.     
  387.         // Make the shark follow the submarine
  388.     if (sharkMid > subMid)
  389.     {
  390.         sharkStructP->vertDelta -= kSharkAcceleration;
  391.         if (sharkStructP->vertDelta < -kSharkMaxSpeed)
  392.             sharkStructP->vertDelta = -kSharkMaxSpeed;
  393.         
  394.             // Make sure the shark didn't move past the sub
  395.         if (sharkMid + sharkStructP->vertDelta < subMid)
  396.         {
  397.             sharkStructP->vertDelta = subMid - sharkMid;
  398.         }
  399.     }
  400.     else if (sharkMid < subMid)
  401.     {
  402.         sharkStructP->vertDelta += kSharkAcceleration;
  403.         if (sharkStructP->vertDelta > kSharkMaxSpeed)
  404.             sharkStructP->vertDelta = kSharkMaxSpeed;
  405.         
  406.             // Make sure the shark didn't move past the sub
  407.         if (sharkMid + sharkStructP->vertDelta > subMid)
  408.         {
  409.             sharkStructP->vertDelta = subMid - sharkMid;
  410.         }
  411.     }
  412.     else if (subStructP->vertDelta == 0)
  413.     {
  414.         sharkStructP->vertDelta = 0;
  415.     }
  416.     
  417.         // Move the shark slower than normal if it was hit recently
  418.     if (sharkStructP->moveDelay > 0)
  419.     {
  420.         sharkStructP->moveDelay--;
  421.         sharkStructP->horizPos += sharkStructP->horizDelta/2;
  422.         sharkStructP->vertPos += sharkStructP->vertDelta/2;
  423.     }
  424.     else
  425.     {
  426.         sharkStructP->horizPos += sharkStructP->horizDelta;
  427.         sharkStructP->vertPos += sharkStructP->vertDelta;
  428.     }
  429.  
  430.  
  431.     SWMoveSprite(sharkSpriteP, sharkStructP->horizPos, sharkStructP->vertPos);
  432.     
  433.         // Turn the shark around if it went past the edge of the screen
  434.     if ( (sharkSpriteP->oldFrameRect.right < sharkSpriteP->moveBoundsRect.left-40 &&
  435.          sharkStructP->horizDelta < 0) ||
  436.          (sharkSpriteP->oldFrameRect.left > sharkSpriteP->moveBoundsRect.right+40 &&
  437.          sharkStructP->horizDelta > 0) )
  438.     {
  439.         sharkStructP->horizDelta = -sharkStructP->horizDelta;
  440.         
  441.             // Change set of frames used to animate the shark
  442.         if (sharkStructP->horizDelta > 0)
  443.         {
  444.             SWSetSpriteFrameRange(sharkSpriteP, 0, 2);
  445.             SWSetCurrentFrameIndex(sharkSpriteP, 0);
  446.         }
  447.         else
  448.         {
  449.             SWSetSpriteFrameRange(sharkSpriteP, 3, 5);
  450.             SWSetCurrentFrameIndex(sharkSpriteP, 3);
  451.         }
  452.     }
  453. }
  454.  
  455.  
  456. ///--------------------------------------------------------------------------------------
  457. //    FishHitDrawProc - Note: this DrawProc requires the sprite to have a maskRgn. If you
  458. //    look at NewSprite(), you'll see that the fish and shark sprites were both loaded 
  459. //    with kFatMask, instead of kPixelMask, so this drawProc could be used for them.
  460. //
  461. //    Note also that since PaintRgn gives us no option to clip our drawing to the dstRect,
  462. //    we turn the dstRect into a region and "clip" the frame's region to the dstRect
  463. //    region with SectRgn. An alternative would be to call ClipRect to set the current
  464. //    clipping region to dstRect before making the call to PaintRgn. (Remembering to 
  465. //    restore the old clipping region when done). This clipping must be done because
  466. //    sometimes (especially in scrolling games) only part of a sprite will be drawn.
  467. ///--------------------------------------------------------------------------------------
  468.  
  469. SW_FUNC void FishHitDrawProc(
  470.     FramePtr srcFrameP,
  471.     FramePtr dstFrameP,
  472.     Rect* srcRect,
  473.     Rect* dstRect)
  474. {
  475.     #pragma        unused(dstFrameP)    // Tell CodeWarrior this variable is unused
  476.     
  477.     if (srcFrameP->maskRgn != NULL)
  478.     {
  479.         Rect rgnRect = (**srcFrameP->maskRgn).rgnBBox;
  480.  
  481.             // move the mask region to the sprite location
  482.         OffsetRgn(srcFrameP->maskRgn,
  483.             (dstRect->left - (srcRect->left - srcFrameP->frameRect.left) - rgnRect.left) 
  484.             + srcFrameP->offsetPoint.h,
  485.             (dstRect->top - (srcRect->top - srcFrameP->frameRect.top) - rgnRect.top)
  486.             + srcFrameP->offsetPoint.v);
  487.         
  488.             // Here we "clip" the srcFrameP->maskRgn with the dstRect.
  489.         RectRgn(gTempRgn, dstRect);
  490.         SectRgn(gTempRgn, srcFrameP->maskRgn, gTempRgn);
  491.         
  492.         ForeColor(whiteColor);
  493.         PaintRgn(gTempRgn);
  494.         ForeColor(blackColor);
  495.     }
  496. }
  497.  
  498.